#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
try:
    inputfile = sys.argv[1]
except:
    sys.exit('Usage: %s <input.py>\nThe "py" extension is important.'%sys.argv[0])
dirName = os.path.dirname(inputfile)
if dirName not in sys.path:
    sys.path.insert(0, dirName)
baseName = os.path.basename(inputfile)
fileName, fileExtension = os.path.splitext(baseName)
assert(fileExtension.lower()=='.py' or fileExtension.lower()=='.pyc')
exec('from %s import paste, cut, FEPfileList, mfptfileList, DynaSingleList, WorOut, DynaOut, PeakH, NCpu'% \
        fileName)

import numpy
import subprocess
import multiprocessing

def peakdet_first(v, delta):
    # mintab: minimal postion; maxtab maximal position
    # find the first barrier
    pmax, pmin = 0, 0
    cluster_num = v.shape[0]
    mx, mn = -numpy.Inf, numpy.Inf

    lookformax = False # look for min first
    
    for i in xrange(cluster_num):
        this = v[i]
        if this > mx:
            mx = this
            mxpos = i
        if this < mn:
            mn = this
            mnpos = i
        
        if lookformax:
            if this < mx-delta:
                maxtab = mxpos
                return maxtab, mintab
        else:
            if this > mn+delta:
                mintab = mnpos
                mx = this
                mxpos = i
                lookformax = True
                pmin+=1
    raise(Exception('Cannot find a barrier!'))
    return None, None



def MakeSingleDyna(FEPfile, mfptfile, Dynaout, PeakH):
    # input: FEPfile, mfptfile
    # output: Dynaout
    # return NGeoClus, number of geometry clusters
    FEP = numpy.fromfile(FEPfile,  sep=' ', dtype='f8')
    FEP.shape = (-1, 2)
    FEPv = numpy.ascontiguousarray(FEP[:, 1],)
    del FEP
    hi, mintab = peakdet_first(FEPv, PeakH) 
    mfpt = numpy.fromfile(mfptfile, sep='\n', dtype='f8')
    NGeoClus = mfpt.shape[0]
    argmfpt = numpy.argsort(mfpt).astype('i4')
    del mfpt

    DynaClus = numpy.empty(NGeoClus, dtype='i4')

    DynaClus[argmfpt[:hi]] = 0
    DynaClus[argmfpt[hi:]] = 1
    # calculate number of digits
    DynaClus.tofile(Dynaout, sep='\n', format='%d')
    return NGeoClus

def MergeDynaout(DynaoutList):
    DynaoutMerge = []
    p1 = subprocess.Popen(['/usr/bin/paste','-d',''] + DynaoutList, bufsize=-1,
        stdout=subprocess.PIPE)
    preID = -1
    preStr = ''
    currID = 1
    dict1 = {}
    while 1:
        line1 = p1.stdout.readline()
        if not line1:
            break
        if line1 == preStr:
            thisID  = preID
        else:
            if line1 in dict1:
                thisID = dict1[line1]
            else:
                thisID = currID
                dict1[line1] = thisID
                currID += 1
            preStr = line1
            preID = thisID
        DynaoutMerge.append(thisID)
    return numpy.array(DynaoutMerge, dtype='i4')


def Wrap(tuple1):
    FEPfile, mfptfile, DynaSingle = tuple1
    MakeSingleDyna(FEPfile, mfptfile, DynaSingle, PeakH)


def Transwor(WorOut,DynaoutMerge, DynaOut):
    p1 = subprocess.Popen(['/usr/bin/cut', '-d', ' ', '-f', '2', WorOut], bufsize=-1, 
            stdout=subprocess.PIPE)
    oldraw = numpy.fromfile(p1.stdout, sep='\n', dtype='i4')-1
    newraw = DynaoutMerge[oldraw]
    newraw.tofile(DynaOut, sep='\n', format='%d')

def main():
    assert(len(FEPfileList)==len(mfptfileList)==len(DynaSingleList))
    Nfiles = len(FEPfileList)
    FileArray = [(FEPfileList[i], mfptfileList[i], DynaSingleList[i]) for i in xrange(Nfiles)]
    P = multiprocessing.Pool(NCpu)
    P.map(Wrap, FileArray)
    DynaoutMerge = 'DynaoutMerge.txt'
    DynaoutMerge = MergeDynaout(DynaSingleList)
    Transwor(WorOut, DynaoutMerge, DynaOut)


if __name__ == '__main__':
    main()
